home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
cmprss.exe
/
CPRESS.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-26
|
2KB
|
112 lines
#include <string.h>
#include "compress.cls"
#include "type.h"
int cpofstream::compress(uchar *inbuff, uint inbuff_len, uchar *outbuff, uchar *hash_tbl[], uint hash_len)
{
uchar *in_idx=inbuff;
uchar *inbuff_end=inbuff+inbuff_len;
uchar *anchor;
uchar *pat_idx;
uint cnt;
uint gap;
uint c;
uint hash;
uint *ctrl_idx=(uint*)outbuff;
uint ctrl_bits;
uint ctrl_cnt=0;
uchar *out_idx=outbuff+sizeof(uint);
uchar *outbuff_end=outbuff+(inbuff_len-48);
if (inbuff_len <= 18)
{
memcpy(outbuff,inbuff,inbuff_len);
return 0-inbuff_len;
}
hash_len--;
while (in_idx < inbuff_end)
{
if (ctrl_cnt++==16)
{
*ctrl_idx=ctrl_bits;
ctrl_cnt=1;
ctrl_idx=(uint*)out_idx;
out_idx+=2;
if (out_idx>outbuff_end)
{
memcpy(outbuff,inbuff,inbuff_len);
return 0-inbuff_len;
}
}
anchor=in_idx;
c=*in_idx++;
while (in_idx < inbuff_end && *in_idx==c && (in_idx-anchor)<4114)
in_idx++;
if ((cnt=in_idx-anchor) > 2)
{
if (cnt<=18)
{
*out_idx++=cnt-3;
*out_idx++=c;
}
else
{
cnt-=19;
*out_idx++=16+(cnt & 0x0F);
*out_idx++=cnt>>4;
*out_idx++=c;
}
ctrl_bits=(ctrl_bits<<1) | 1;
continue;
}
in_idx=anchor;
if ((inbuff_end - in_idx) > 2)
{
hash=((((in_idx[0] & 15) << 8) | in_idx[1]) ^ ((in_idx[0]>>4) | (in_idx[2]<<4))) & hash_len;
pat_idx=hash_tbl[hash];
hash_tbl[hash]=in_idx;
if ((gap=in_idx-pat_idx) <= 4098)
{
while (in_idx < inbuff_end && pat_idx < anchor && *pat_idx==*in_idx && (in_idx-anchor) < 271)
{
in_idx++;
pat_idx++;
}
if ((cnt=in_idx-anchor) > 2)
{
gap-=3;
if (cnt<=15)
{
*out_idx++=(cnt<<4) + (gap & 0x0F);
*out_idx++=gap >> 4;
}
else
{
*out_idx++=32 + (gap & 0x0F);
*out_idx++=gap >> 4;
*out_idx++=cnt-16;
}
ctrl_bits=(ctrl_bits<<1) | 1;
continue;
}
}
}
*out_idx++=c;
in_idx=++anchor;
ctrl_bits<<=1;
}
ctrl_bits<<=(16-ctrl_cnt);
*ctrl_idx=ctrl_bits;
return out_idx-outbuff;
}